package nillearn

import (
	"fmt"
	"unsafe"
)

func NilLearn() {
	//make和new函数
	//var p *int //声明了一个变量p, 但是变量没有初始值，也就没有内存
	//*p = 10    //这样是错的

	//默认值：int,byte,rune,float,bool,string这些类型都是有默认值的。在声明这些变量的时候，go会分配给这个变量一个地址，并把默认值，放到这个内存空间中
	//指针，切片，map, 接口，这些类型的默认值都是nil,没有分配内存地址，如果想要分配地址，需要使用new函数
	var a int
	a = 10
	fmt.Println(a)

	//对于指针来说，或者其他默认值为nil的情况，如何声明的时候就分配内存？new
	var p *int = new(int) //go的编译器就知道先申请一个内存空间（地址），并将内存中的值全部设置为0
	*p = 20
	fmt.Println(*p)

	//var info map[string]string
	//info["name"]="john" //也是会报错的
	//除了new函数可以申请内存以外，还有一个函数就是make
	//更加常用的是make,make函数一般用于切片，map的声明
	var info = make(map[string]string)
	info["name"] = "John"
	fmt.Println(info)

	//new函数返回的是这个值得地址 - 指针
	//make函数返回的是指定类型的实例

	var info2 map[string]string
	if info2 == nil {
		fmt.Println("map的默认值是nil")
	}

	var slice []int
	if slice == nil {
		fmt.Println("slice的默认值是nil")
	}

	var err error
	if err == nil {
		fmt.Println("error的默认值是nil")
	}

	//python中的None和go中的零值nil是不一样的，python的None是全局唯一的“对象”
	//go语言中的nil是唯一可以用来表示部分类型零值的标识符，他可以代表许多不同内存布局的值
	fmt.Println(unsafe.Sizeof(info2), unsafe.Sizeof(slice), unsafe.Sizeof(err))
}
